import pythoncom
from win32com.server.register import UseCommandLine
from win32com.server.exception import COMException
import random
import time
from threading import Thread

class OPCDAServer:
    _public_methods_ = ['Read', 'Write', 'GetItemList']
    _reg_progid_ = "Python.OPCDA.Simulator"
    _reg_clsid_ = pythoncom.CreateGuid()
    
    def __init__(self):
        print("初始化 OPC DA 服务器...")
        self.tags = {
            "Temperature": {"value": 25.0, "quality": 192},
            "Pressure": {"value": 1.0, "quality": 192},
            "FlowRate": {"value": 100.0, "quality": 192},
            "Status": {"value": "Running", "quality": 192}
        }
        self._running = True
        self._update_thread = Thread(target=self._update_values, daemon=True)
        self._update_thread.start()
    
    def _update_values(self):
        while self._running:
            self.tags["Temperature"]["value"] = round(25 + random.uniform(-2, 2), 2)
            self.tags["Pressure"]["value"] = round(1 + random.uniform(-0.1, 0.1), 2)
            self.tags["FlowRate"]["value"] = round(100 + random.uniform(-10, 10), 2)
            time.sleep(1)
    
    def Read(self, item_ids):
        print(f"读取标签: {item_ids}")
        results = []
        for item_id in item_ids:
            if item_id in self.tags:
                tag = self.tags[item_id]
                results.append([
                    item_id,
                    tag["value"],
                    tag["quality"],
                    time.time()
                ])
            else:
                raise COMException(description=f"Tag {item_id} not found")
        return results
    
    def Write(self, items):
        print(f"写入标签: {items}")
        results = []
        for item in items:
            item_id = item[0]  # 现在items是列表而不是字典
            value = item[1]
            if item_id in self.tags:
                self.tags[item_id]["value"] = value
                results.append(True)
            else:
                results.append(False)
        return results
    
    def GetItemList(self):
        print("获取标签列表")
        return list(self.tags.keys())
    
    def stop(self):
        self._running = False
        self._update_thread.join()

if __name__ == '__main__':
    print("注册 OPC DA 服务器...")
    UseCommandLine(OPCDAServer)
    print("服务器已启动，等待客户端连接...")
    try:
        while True: time.sleep(1)
    except KeyboardInterrupt:
        print("服务器关闭")